package com.lotustong.im4d.views;


import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Vector;

import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.DragSource;
import org.eclipse.swt.dnd.DragSourceEvent;
import org.eclipse.swt.dnd.DragSourceListener;
import org.eclipse.swt.dnd.DropTarget;
import org.eclipse.swt.dnd.DropTargetAdapter;
import org.eclipse.swt.dnd.DropTargetEvent;
import org.eclipse.swt.dnd.FileTransfer;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.actions.ActionContext;
import org.eclipse.ui.actions.ActionFactory;
import org.eclipse.ui.part.ViewPart;

import com.lotustong.im4d.action.SetAction;
import com.lotustong.im4d.ipmsg.swt.Messenger;
import com.lotustong.im4d.util.Constants;
import com.lotustong.im4d.util.FileUtil;





/**
 * This sample class demonstrates how to plug-in a new
 * workbench view. The view shows data obtained from the
 * model. The sample creates a dummy model on the fly,
 * but a real implementation would connect to the model
 * available either in this or another plug-in (e.g. the workspace).
 * The view is connected to the model using a content provider.
 * <p>
 * The view uses a label provider to define how model
 * objects should be presented in the view. Each
 * view can present the same model objects using
 * different labels and icons, if needed. Alternatively,
 * a single label provider can be shared between views
 * in order to ensure that objects of the same type are
 * presented in the same way everywhere.
 * <p>
 */

public class UserView extends ViewPart {

    private Table   table;
    private Table 	leftTree;
    private TableItem[] leftTreeItems;
    private Text    text;
    private Button  send;
    private Button  lock;
	
    private String  userName;
    private String  groupName;
    private Messenger messenger;
    
    private UserViewActionGroup userViewActionGroup;
    

    private boolean debug;
    
	/**
	 * The constructor.
	 */
	public UserView() {
	}
	public boolean getDebugMode(){
	    return this.debug;
	}
	/**
	 * This is a callback that will allow us
	 * to create the viewer and initialize it.
	 */
	public void createPartControl(Composite parent) {
		
		initComponents(parent);
		
		try {
			messenger = new Messenger(this.userName,this.userName,this.groupName,this);
	        messenger.login();
	        messenger.start();
		} catch (IOException e) {
			// TODO Auto-generated catsch block
			e.printStackTrace();
		}
	}

	/**
	 * Passing the focus request to the viewer's control.
	 */
	public void setFocus() {
		table.setFocus();
	}
	
    private void initComponents(Composite parent){
    	
    	
    	
    	
		IToolBarManager toolBar = getViewSite().getActionBars().getToolBarManager();
		toolBar.add(new SetAction(this));
    	
        SashForm sash = new SashForm(parent,SWT.VERTICAL);
		
        table = new Table(sash,SWT.MULTI|SWT.FULL_SELECTION|SWT.BORDER);
        table.setHeaderVisible(true);
        String[] cols = {"User","Group","Host"};
        for(int i=0;i<cols.length;i++){
            TableColumn col = new TableColumn(table,SWT.LEFT);
            col.setText(cols[i]);
            col.setWidth(100);
			if(i==0){
				col.addSelectionListener(new UserSortListener());
			} else if(i==1){
				col.addSelectionListener(new GroupSortListener());
			} else if(i==2){
				col.addSelectionListener(new HostSortListener());
			}
        }
        //put local user into table
        this.userName = System.getProperty("user.name");
        this.groupName = "Group_Test";
        String ip = "";
        try {
			ip = InetAddress.getLocalHost().getHostAddress();
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
//        TableItem item = new TableItem(table,SWT.NULL);
//        String[] data = {this.userName,this.groupName,ip};
//        item.setText(data);
        //file tree
        leftTree = new Table(sash,SWT.MULTI | SWT.FULL_SELECTION | SWT.BORDER );
        leftTree.setHeaderVisible(true);
        TableColumn col = new TableColumn(leftTree,SWT.LEFT);
        col.setText("Attach a file");
        col.setWidth(50);
              
        
        Composite composite = new Composite(sash,SWT.NULL);
        
        GridLayout layout = new GridLayout();
        layout.horizontalSpacing = 0;
        layout.verticalSpacing   = 0;
        layout.marginHeight      = 0;
        layout.marginWidth       = 0;
        composite.setLayout(layout);

        //text
        text = new Text(composite,SWT.WRAP|SWT.V_SCROLL|SWT.MULTI|SWT.BORDER);
        GridData gridData1 = new GridData(GridData.FILL_BOTH);
        text.setLayoutData(gridData1);
        //TODO:dragdrop
        setFileDragDrop(text);
        //buttons
        Composite buttons = new Composite(composite,SWT.NULL);
        GridData gridData2 = new GridData(GridData.HORIZONTAL_ALIGN_END);
        buttons.setLayoutData(gridData2);
        
        RowLayout layout2 = new RowLayout();
        buttons.setLayout(layout2);
        
        send = new Button(buttons,SWT.NULL);
        send.setText("      send      ");
        send.addSelectionListener(new SendListener());
        
        lock = new Button(buttons,SWT.CHECK);
        lock.setText("lock");
        
        Button list = new Button(buttons,SWT.NULL);
        list.setText("Attach List");
        list.addSelectionListener(new GetAttachListListener());
        
    }
    
    
    /**
     * 
     */
class UserSortListener extends SelectionAdapter {
		
		public void widgetSelected(SelectionEvent e){
			
			if(table.getItemCount()==0){ return; }
			
			TableItem[] items = table.getItems();
			Arrays.sort(items,new UserComparator());
			Vector vec = new Vector();
			for(int i=0;i<items.length;i++){
				String[] data = {items[i].getText(0),items[i].getText(1),items[i].getText(2)};
				vec.add(data);
			}
			
			table.removeAll();
			for(int i=0;i<vec.size();i++){
				TableItem item = new TableItem(table,SWT.NULL);
				item.setText((String[])vec.get(i));
			}
		}
	}
	
	/**
	 *  
	 */
	class GroupSortListener extends SelectionAdapter {
		
		public void widgetSelected(SelectionEvent e){
			
			if(table.getItemCount()==0){ return; }
			
			TableItem[] items = table.getItems();
			Arrays.sort(items,new GroupComparator());
			Vector vec = new Vector();
			int spaceCount = 0;
			int sameCount  = 1;
			for(int i=0;i<items.length;i++){
				String[] data = {items[i].getText(0),items[i].getText(1),items[i].getText(2)};
				boolean regFlag = false;
				if(i!=0 && data[1].equals(groupName) && !data[1].equals("")){
					vec.insertElementAt(data,sameCount);
					sameCount++;
					regFlag = true;
				} else if(i>1){
					String[] prev = (String[])vec.get(i-1);
					if(prev[1].equals("")){
						vec.insertElementAt(data,i-spaceCount);
						regFlag = true;
						if(data[1].equals("")){ spaceCount++; }
					}
				}
				if(!regFlag){
					vec.add(data);
					if(data[1].equals("") && i!=0){ spaceCount++; }
				}
			}
			
			table.removeAll();
			for(int i=0;i<vec.size();i++){
				TableItem item = new TableItem(table,SWT.NULL);
				item.setText((String[])vec.get(i));
			}
			
		}
	}

	/**
	 *  
	 */
	class HostSortListener extends SelectionAdapter {
		
		public void widgetSelected(SelectionEvent e){
			
			if(table.getItemCount()==0){ return; }
			
			TableItem[] items = table.getItems();
			Arrays.sort(items,new HostComparator());
			Vector vec = new Vector();
			for(int i=0;i<items.length;i++){
				String[] data = {items[i].getText(0),items[i].getText(1),items[i].getText(2)};
				vec.add(data);
			}
			
			table.removeAll();
			for(int i=0;i<vec.size();i++){
				TableItem item = new TableItem(table,SWT.NULL);
				item.setText((String[])vec.get(i));
			}
		}
	}


	class UserComparator implements Comparator {
		
		public int compare(Object o1,Object o2){
			TableItem item1 = (TableItem)o1;
			TableItem item2 = (TableItem)o2;
			
			String user1 = item1.getText(0);
			String user2 = item2.getText(0);
			
			if(userName.equals(user1)){
				return -1;
			}
			
			return user1.compareTo(user2);
		}
	}
	

	class GroupComparator implements Comparator {
		
		public int compare(Object o1,Object o2){
			TableItem item1 = (TableItem)o1;
			TableItem item2 = (TableItem)o2;
			
			String group1 = item1.getText(1);
			String group2 = item2.getText(1);
			
			if(groupName.equals(group1)){
				return -1;
			}
			
			return group1.compareTo(group2);
		}
	}
	

	class HostComparator implements Comparator {
		
		private String hostName;
		
		public HostComparator(){
			TableItem item = table.getItem(0);
			this.hostName = item.getText(2);
		}
		
		public int compare(Object o1,Object o2){
			TableItem item1 = (TableItem)o1;
			TableItem item2 = (TableItem)o2;
			
			String host1 = item1.getText(2);
			String host2 = item2.getText(2);
			
			if(this.hostName.equals(host1)){
				return -1;
			}
			
			return host1.compareTo(host2);
		}
	}
	
    class SendListener extends SelectionAdapter {

        public void widgetSelected(SelectionEvent e){
            TableItem[] items = table.getSelection();
            if(items==null || items.length==0){
                return;
            }
            
            try {
                String msg = text.getText();
                
                leftTreeItems = leftTree.getSelection();
                if(leftTreeItems!=null && leftTreeItems.length!=0){
                	msg = msg + Constants.FILE_BEIGN_MARK;
	                for(int j=0;j<leftTreeItems.length;j++){
	                	String fileName = leftTreeItems[j].getText();
	                	
	                	String fileContent = FileUtil.getFileContent(fileName);
	                	msg = msg + fileName;
	                	msg = msg + Constants.FILE_SEPARATER_FILE_MARK;
	                	msg = msg + fileContent;
	                	if(j!=(leftTreeItems.length-1)){
	                		msg = msg + Constants.FILE_SEPARATER_LIST_MARK;
	                	}
	                } 
                }
                boolean flag = lock.getSelection();
                for(int i=0;i<items.length;i++){
                	String user = items[i].getText(0);
                    String host = items[i].getText(2);
                    messenger.sendMsg(user,host,msg,flag);
                }
                
                text.setText("");
                lock.setSelection(false);
                table.deselectAll();

            } catch(Exception ex){
                ex.printStackTrace();
                MessageBox mesBox = new MessageBox(getViewSite().getShell(),SWT.OK|SWT.ICON_ERROR);
                mesBox.setText("error");
                mesBox.setMessage(ex.toString());
                mesBox.open();
            }
        }
    }
    public void addMember(String userName,String groupName,String host){
        if(userName.equals(this.userName) && groupName.equals(this.groupName)){
            // 
	        TableItem item = new TableItem(table,SWT.NULL,0);
	        String[] data = {userName,groupName,host};
	        item.setText(data);
	        //IViewSite a =null;
	        
        } else {
            // 
	        TableItem item = new TableItem(table,SWT.NULL);
	        String[] data = {userName,groupName,host};
	        item.setText(data);
        }
    }
    //
    class GetAttachListListener extends SelectionAdapter {

        public void widgetSelected(SelectionEvent e){
            TableItem[] items = leftTree.getSelection();
            if(items==null || items.length==0){
                return;
            }
            
            try {
                String msg = text.getText(); 
                for(int i=0;i<items.length;i++){
                	String type = FileUtil.getFiletype(items[i].getText());
                	if(type.equals("txt") || type.equals("log")){
	                	msg = msg + "<<---\n";
	                	msg = msg + FileUtil.getFileContent(items[i].getText());
	                	msg = msg + "\n>>---\n";
	                	text.setText(msg);
                	}
                }
                table.deselectAll();

            } catch(Exception ex){
                ex.printStackTrace();
            }
        }
    }
    //
    /**
     * 
     * 
     * @param host 
     */
    public void removeMember(String host){
        if(getViewSite().getShell().isDisposed()){
            return;
        }
        for(int i=0;i<table.getItemCount();i++){
            TableItem item = table.getItem(i);
            if(item.getText(2).equals(host)){
                table.remove(i);
                break;
            }
        }
    }
    public static void setDragDrop (final Label lable) {
    	
    	Transfer[] types = new Transfer[] {TextTransfer.getInstance()};
    	int operations = DND.DROP_MOVE | DND.DROP_COPY | DND.DROP_LINK;
    	
    	final DragSource source = new DragSource (lable, operations);
    	source.setTransfer(types);
    	source.addDragListener (new DragSourceListener () {
    		public void dragStart(DragSourceEvent event) {
    			event.doit = (lable.getText ().length () != 0);
    		}
    		public void dragSetData (DragSourceEvent event) {
    			event.data = lable.getText ();
    		}
    		public void dragFinished(DragSourceEvent event) {
    			if (event.detail == DND.DROP_MOVE)
    				lable.setText ("");
    		}
    	});

    	DropTarget target = new DropTarget(lable, operations);
    	target.setTransfer(types);
    	target.addDropListener (new DropTargetAdapter() {
    		public void drop(DropTargetEvent event) {
    			if (event.data == null) {
    				event.detail = DND.DROP_NONE;
    				return;
    			}
    			lable.setText ((String) event.data);
    		}
    	});
    }
    //
   public void setFileDragDrop (final Text text) {
    	
	   	final TextTransfer textTransfer = TextTransfer.getInstance();
	   	final FileTransfer fileTransfer = FileTransfer.getInstance();
    	Transfer[] types = new Transfer[] {textTransfer,fileTransfer};
    	int operations = DND.DROP_MOVE | DND.DROP_COPY | DND.DROP_LINK;
    	
//    	final DragSource source = new DragSource (text, operations);
//    	source.setTransfer(types);
//    	source.addDragListener (new DragSourceListener () {
//    		public void dragStart(DragSourceEvent event) {
//    			event.doit = (text.getText ().length () != 0);
//    		}
//    		public void dragSetData (DragSourceEvent event) {
//    			event.data = text.getText ();
//    		}
//    		public void dragFinished(DragSourceEvent event) {
//    			if (event.detail == DND.DROP_MOVE)
//    				text.setText ("");
//    		}
//    	});

    	DropTarget target = new DropTarget(text, operations);
    	target.setTransfer(types);
    	target.addDropListener (new DropTargetAdapter() {
    		public void drop(DropTargetEvent event) {
    			if (event.data == null) {
    				event.detail = DND.DROP_NONE;
    				return;
    			}
    	        if (fileTransfer.isSupportedType(event.currentDataType)){
        			String[] strArray = (String[])event.data;
        			StringBuffer temp = new StringBuffer();
        			temp.append(text.getText());
        			for(int i=0;i<strArray.length;i++){
        				TableItem leftTableItem = new TableItem(leftTree,SWT.NULL);
        				leftTableItem.setText(FileUtil.getFileName(strArray[i]));
        			}

        			text.setText(temp.toString());
    	        }

    		}
    	});
    }
   
}